#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>

#include<sys/shm.h>
#include "my_shm_pubsub.h"
 
typedef union semun
{
	int val;
}semun;
 
int sem_init(int key);
 
void sem_p(int id,int sem);
 
void sem_v(int id,int sem);
 
void sem_del(int id);

int sem_init(int key)
{
	int semid;
	semid=semget((key_t)key,0,0666);
	if(semid==-1)
	{
		semid=semget((key_t)key,1,0666 | IPC_CREAT);
 
		semun mu;
		mu.val=1;

		semctl(semid,0,SETVAL,mu);
	}
	return semid;
}
 
void sem_p(int id,int sem)
{
	struct sembuf buff;
	buff.sem_num=sem;
	buff.sem_op=-1;
	buff.sem_flg=SEM_UNDO;
	semop(id,&buff,1);
}
 
void sem_v(int id,int sem)
{
	struct sembuf buff;
	buff.sem_num=sem;
	buff.sem_op=1;
	buff.sem_flg=SEM_UNDO;
	semop(id,&buff,1);
}
 
void sem_del(int id)
{
	semctl(id,0,IPC_RMID);
}

//因为共享内存中可能存在的竟态条件，因此共享内存需要和其他进程间通讯方式一起使用
 
typedef struct shm_test_a
{
    /* data */
    int index;
    int time;
    unsigned char data[1920*1080*3];
};
 
void callback(shm::publish::Memblock *msg) 
{
    shm_test_a *a;
    a = (shm_test_a *)msg->ptr;
    // int a = *(int *)msg->ptr;
	printf("asdf\n");
    // printf("index:%x\n", a->index);
}

int main()
{
    #if 1
	int shmid=shmget((key_t)1234,1024*1024*10,0666 | IPC_CREAT);
	assert(shmid!=-1);
 
	char *ptrb=(char *)shmat(shmid,NULL,0);
	assert(ptrb!=(char *)-1);
 
	int semid=sem_init(123);
    
	while(1)
	{
		sem_p(semid,0);
		// if((strcmp(ptrb,"end")==0) || (strcmp(ptrb,"END")==0))
		// {
		// 	break;
		// }
		// int i=0;
		// for(;i<strlen(ptrb);i++)
		// {
		// 	if(ptrb[i]>='A' &&  ptrb[i]<='Z')  //将大写字符转换成小写字符
		// 	{
		// 		ptrb[i]=ptrb[i]+32;
		// 	}
		// 	printf("%c\n",ptrb[i]);     //观看效果
		//     sleep(1);
		// }
		// printf("%s\n",ptrb);
        shm_test_a *b;
        b =  (shm_test_a *)ptrb;
        printf("index:%d\n", b->index);

		sem_v(semid,0);
	}
	shmdt(ptrb);
    #else

    shm::publish::Subscriber sub("mytest", callback);
    while (1)
    {
        sub.spin_once();
        usleep(100);
    }
    #endif

	return 0;
}